/**
 * 游戏逻辑管理器
 * Author       : jxyi (jxyi@bainainfo.com)
 * Create Time  : 2017.2.26
 */

module.exports = cc.Class({
    ctor: function(){
        // 游戏状态相关参数
        this.gameStatus = {
            status: 'stop', // 游戏状态，['running', 'stop', 'pause']
            time: 0,        // 游戏时间，秒
            refreshTime: 2, // 敌人刷新间隔，秒
        },

        // 地图相关参数，包括地图大小、边界等信息
        this.map = {
            size: null
        };

        // 玩家实例引用
        this.player = null;

        // 子弹实例引用
        this.bulletMap = {};

        // 敌人实例引用
        this.enemyMap = {};

        // 刷新敌人冷却时间
        this.refreshEnemyTime = 0;

        // 子弹可用的 id （每生成一个子弹 id + 1)
        this.bulletValidId = 0;

        // 敌人可用的 id （每生成一个敌人 id + 1)
        this.enemyValidId = 0;
    },

    // 设置地图相关配置信息
    setMapInfo: function(size){
        this.map.size = size;
        this.map.rect = cc.rect(-size.x / 2, -size.y / 2, size.x, size.y);
    },

    /**
     * 设置主角实例引用
     * param: player，主角实例引用
     */
    setPlayer: function(player){
        this.player = player;
    },

    /**
     * 添加子弹到管理器中
     * param: bullet，子弹实例
     */
    addBullet: function(bullet){
        // 子弹实体对象不可为 undefined
        if (bullet == undefined){
            cc.log('[BattleManager addBullet] bullet is undefined');
            return;
        }

        // 子弹实体对象必须为一个 object 对象
        if (typeof bullet != 'object'){
            cc.log('[BattleManager addBullet] bullet is not an object');
            return;
        }

        // 保存子单显示对象
        this.bulletMap[bullet.id] = bullet;
    },

    /**
     * 添加敌人到管理器中
     * param: enemy，敌人实例
     */
    addEnemy: function(enemy){
        // 敌人实体对象不可为 undefined
        if (enemy == undefined){
            cc.log('[BattleManager addEnemy] enemy is undefined');
            return;
        }

        // 敌人实体对象必须为一个 object 对象
        if (typeof enemy != 'object'){
            cc.log('[BattleManager addEnemy] enemy is not an object');
            return;
        }

        // 保存敌人显示对象
        this.enemyMap[enemy.id] = enemy;
    },

    /**
     * 创建子弹
     */
    createBullet: function(){
        // if (this.gameStatus.status != 'running'){
        //     cc.log('[BattleManager createBullet] game is not running, can not create bullet');
        //     return;
        // }

        game.dispatchEvent(game.GameEvent.BULLET_ADD, {
                id: this.bulletValidId,
                x: this.player.x,
                y: this.player.y,
                direct: Math.angleToRadian(-game.playerComponent.getPlaneRotation()),
                speed: 8
            }
        );

        ++this.bulletValidId;
    },

    /**
     * 每帧循环控制，遍历子弹与敌人并进行碰撞检测
     */
    update: function(dt){
        if (this.gameStatus.status == 'stop' || this.gameStatus.status == 'pause'){
            return;
        }

        // if (this.player == null){
        //     cc.log('[BattleManager update] game is running, but player is null !');
        //     return;
        // }

        this.time += dt;

        // 更新子弹位置
        this.updateBulletPos(this.bulletMap, dt);

        // 检查子弹是否击中
        this.checkHit(this.bulletMap, this.enemyMap);

        // 刷新敌人
        this.refreshEnemy(dt);
    },

    /**
     * 更新子弹位置
     * param: bulletMap，子弹实例的 map
     *      dt，经过的时间
     */
    updateBulletPos: function(bulletMap){
        // if (typeof bulletMap !== 'object'){
        //     cc.log('[BattleManager updateBulletPos] bulletMap is not map');
        //     return;
        // }

        for (var key in bulletMap){
            var bullet = bulletMap[key];            
            var pos    = bullet.getPosition();
            bullet.setPositionX(pos.x + bullet.speed * Math.cos(bullet.direct));
            bullet.setPositionY(pos.y + bullet.speed * Math.sin(bullet.direct));

            // 子弹移动到地图以外
            if (! this.map.rect.contains(bullet.getPosition())){
                bullet.parent.removeChild(bullet, true);
                delete bulletMap[key];
            }
        }
    },

    /**
     * 检测碰撞，若发生碰撞将发出碰撞消息 ENEMY_HIT
     * param：bulletMap，子弹实例的 map
     *      planeMap，飞机实例的 map
     */
    checkHit: function(bulletMap, planeMap){
        if (typeof bulletMap !== 'object'){
            cc.log('[BattleManager checkHit] bulletMap is not map');
            return;
        }

        if (typeof planeMap !== 'object'){
            cc.log('[BattleManager checkHit] planeMap is not map');
            return;
        }
        

        // 验证所有子弹是否碰到飞机
        for (var bulletKey in bulletMap){
            var bullet = bulletMap[bulletKey];

            for (var planeKey in planeMap){    
                var plane = planeMap[planeKey];

                if (plane.getBoundingBox().contains(bullet.getPosition())){

                    game.dispatchEvent(game.GameEvent.ENEMY_HIT, {
                        id: plane.id,   // 目标实例的 id
                        x: plane.x,     // 目标实例的 x 坐标
                        y: plane.y      // 目标实例的 y 坐标
                    });
                    
                    // 碰到敌人后删除子弹
                    bullet.parent.removeChild(bullet, true);
                    delete bulletMap[bulletKey];

                    // 碰到敌人后删除敌人
                    plane.parent.removeChild(plane, true);
                    delete planeMap[planeKey];
                    break;
                }
            }
        }
    },

    /**
     * 刷新敌人
     */
    refreshEnemy: function(dt){
        this.refreshEnemyTime += dt;
        if (this.refreshEnemyTime > this.gameStatus.refreshTime){
            game.dispatchEvent(game.GameEvent.ENEMY_ADD, {
                id: this.enemyValidId,
                x: Math.random() * this.map.size.x - this.map.size.x / 2,
                y: Math.random() * this.map.size.y - this.map.size.y / 2,
            });

            ++this.enemyValidId;
            this.refreshEnemyTime = 0;
        }
    },

    /**
     * 开始游戏。manager 将开始主循环计算
     */
    startGame: function(){
        if (this.gameStatus.status == 'stop'){
            this.gameStatus.status = 'running';
            cc.director.getScheduler().scheduleUpdate(this, 0, false, this.update.bind(this));
        }
    },

    // /**
    //  * 停止游戏。manager 将停止主循环计算，并清空游戏数据
    //  */
    // stopGame: function(){
    //     if (this.gameStatus.status == 'running' || this.gameStatus.status == 'pause'){
    //         this.gameStatus.status = 'stop';
    //         cc.director.getScheduler().unscheduleUpdate(this);
    //     }
    // },

    // /**
    //  * 暂停游戏。manager 将暂停主循环计算，游戏数据将保留
    //  */
    // pauseGame: function(){
    //     if (this.gameStatus.status == 'running'){
    //         this.gameStatus.status = 'pause';
    //     }
    // },

    // /**
    //  * 继续游戏。manager 将使用上次暂停时的游戏数据继续进行主循环计算
    //  */
    // resumeGame: function(){
    //     if (this.gameStatus.status == 'pause'){
    //         this.gameStatus.status = 'running';
    //     }
    // },
});



